#ifndef _USART_H_
#define _USART_H_

#include "../../Component.h"
#include<avr/io.h>
#include<avr/interrupt.h>
#include "../../../bit/bit.h"

namespace Hardware
{
namespace Avr
{

	typedef struct USART_CONFIG
	{
		unsigned char receive : 1;
		unsigned char transmit : 1;
		unsigned char empty : 1;
		unsigned char doubleSpeed : 1;
		unsigned char multiprocessorMode : 1;
		unsigned char receiveInterrupt : 1;
		unsigned char transmitInterrupt : 1;
		unsigned char emptyInterrupt : 1;
		unsigned char receiver : 1;
		unsigned char transmitter : 1;
		unsigned char size : 3;
		unsigned char select : 1;
		unsigned char mode : 1;
		unsigned char parity : 2;
		unsigned char stop : 1;
		unsigned char polarity : 1;
		unsigned char select2 : 1;
		unsigned long int baudRate : 12;
		
	} UsartConfig;

	typedef struct USART_DATA
	{
		unsigned long int data : 9;
	} UsartData;

	class Usart : public Component<UsartConfig, UsartData>
	{
		public :

		
		Usart(){}
		Usart(UsartConfig c){configuration=c;}
		void config()
		{
			//set receive complete
			UCSRA = SetBit(UCSRA, RXC, configuration.receive);
			//set transmit complete
			UCSRA = SetBit(UCSRA, TXC, configuration.transmit);
			//set empty
			UCSRA = SetBit(UCSRA, UDRE, configuration.empty);
			//set double speed
			UCSRA = SetBit(UCSRA, U2X, configuration.doubleSpeed);
			//multiprocessorMode
			UCSRA = SetBit(UCSRA, MPCM,
					 configuration.multiprocessorMode);
			//receive interrupt
			UCSRB = SetBit(UCSRB, RXCIE,	
					 configuration.receiveInterrupt);
			//transmit interrupt
			UCSRB = SetBit(UCSRB, TXCIE,
					 configuration.transmitInterrupt);
			//empty interrupt
			UCSRB = SetBit(UCSRB, UDRIE, 
					configuration.emptyInterrupt);
			//receiver 
			UCSRB = SetBit(UCSRB, RXEN,
					configuration.receiver);
			//transmitter
			UCSRB = SetBit(UCSRB, TXEN,
					configuration.transmitter);
			//set size.
			UCSRB = SetBit(UCSRB, UCSZ2, (configuration.size>>2));
			UCSRC = SetBitGroup(UCSRC, 2, UCSZ0,
						(configuration.size&0x04));
			//set select
			UCSRC = SetBit(UCSRC, URSEL, configuration.select);
			//set mode
			UCSRC = SetBit(UCSRC, UMSEL, configuration.mode);
			//set parity
			UCSRC = SetBitGroup(UCSRC, 2, UPM0,
					 configuration.parity);
			//set stop
			UCSRC = SetBit(UCSRC, USBS, configuration.stop);
			//set polarity
			UCSRC = SetBit(UCSRC, UCPOL, configuration.polarity);
			//set select 2
			UBRRH = SetBit(UBRRH, URSEL, configuration.select2);
			//set baud rate.
			UBRRH = SetBitGroup(UBRRH, 4, 0, 
					(configuration.baudRate>>8));
			UBRRL = (configuration.baudRate & 0x00FF);
			
			
		}
		void run(){}
	};
}
}




#endif
